package com.jlkf.service.impl;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URLEncoder;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Random;
import java.util.SortedMap;
import java.util.TreeMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alipay.api.internal.util.AlipaySignature;
import com.jlkf.dao.TblCourseMapper;
import com.jlkf.dao.TblIntegralSetMapper;
import com.jlkf.dao.TblMessageMapper;
import com.jlkf.dao.TblOrderMapper;
import com.jlkf.dao.TblUserMapper;
import com.jlkf.dao.TblUserPurseInfoMapper;
import com.jlkf.dao.TblVipInfoMapper;
import com.jlkf.pojo.TblIntegralSet;
import com.jlkf.pojo.TblMessage;
import com.jlkf.pojo.TblOrder;
import com.jlkf.pojo.TblUser;
import com.jlkf.pojo.TblUserPurseInfo;
import com.jlkf.pojo.TblVipInfo;
import com.jlkf.service.PayOrderService;
import com.platform.server.response.response.pojo.ReturnData;
import com.platform.server.util.AlipayCons;
import com.platform.server.util.AlipayUtil;
import com.platform.server.util.CfbpayDemoUtils;
import com.platform.server.util.DateUtils;
import com.platform.server.util.HttpUtil;
import com.platform.server.util.WeixinCons;
import com.platform.server.util.WeixinPayUtil;
import com.platform.server.util.WxpayDemoUtils;
import com.platform.server.util.XMLUtil;

import net.sf.json.JSONObject;

/**
 * Created by Administrator on 2017/5/17 0017.
 */
@Service
public class PayOrderServiceImpl implements PayOrderService{
	
    /**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	protected Logger logger = LoggerFactory.getLogger(getClass());
	
	@Autowired
	private TblUserMapper tblUserMapper;
	
	@Autowired
	private TblOrderMapper tblOrderMapper;
	
	@Autowired
	private TblVipInfoMapper tblVipInfoMapper;
	
	@Autowired
	private TblIntegralSetMapper tblIntegralSetMapper;
	
	@Autowired
	private TblUserPurseInfoMapper tblUserPurseInfoMapper;
	
	@Autowired
	private TblCourseMapper tblCourseMapper;
	
	@Autowired
	private TblMessageMapper tblMessageMapper;
	
	
	@Override
	public ReturnData BalanceRecharge(Long userId, Double payMoney,String ip,Integer payWay) throws Exception {
		// TODO Auto-generated method stub
		if(userId==null ||payMoney==null || ip==null){
			return new ReturnData(500,"传入参数有误");
		}
		TblUser user = tblUserMapper.selectByPrimaryKeys(userId);
		String orderid = WxpayDemoUtils.getRandomString(16);
		StringBuffer names = new StringBuffer();
		names.append(user.getgUserName());
		StringBuffer rechargePay = new StringBuffer(names).append("充值金额：" + payMoney);
		if(payWay==1){ //微信支付
			return WxpayDemoUtils.wxPay(names.toString(), orderid, payMoney.toString(),ip,userId+"",2);
		}else if(payWay==2){ //支付宝支付
			return CfbpayDemoUtils.returnAlipayPayParam(names.toString(), names.toString(), orderid, payMoney.toString(),userId+"",2);
		}else if (payWay==3){ //微信扫码支付
			return WxpayDemoUtils.wxPublicPay(names.toString(), orderid, (int) (payMoney*100), userId+"", ip, 2);
		}else if(payWay==4){ //苹果内购
			//计算赠送积分
            TblIntegralSet integralSet = tblIntegralSetMapper.selectByType(1);
    	    int num = (int)Math.floor(payMoney/integralSet.getMoney());
    	    int integral = num*integralSet.getIntegral();
         
            //增加用户钱包金额
			TblUser tuser = new TblUser();
			tuser.setgId(Long.valueOf(userId));
			tuser.setgUserMoney(user.getgUserMoney() + payMoney);
			tuser.setgUserIntegral(user.getgUserIntegral()+integral);
			int flag1 = tblUserMapper.updateByPrimaryKeySelective(tuser);	
			
			//新增钱包明细
			TblUserPurseInfo purseInfo = new TblUserPurseInfo();
			purseInfo.setgContent("苹果内购充值");
			purseInfo.setgCreatetime(new Date());
			purseInfo.setgMoney(payMoney);
			purseInfo.setgStatus(1);
			purseInfo.setgTitle("苹果内购充值");
			purseInfo.setgType(1);
			purseInfo.setgBalance(user.getgUserMoney() + payMoney);
			purseInfo.setgUserid(Long.valueOf(userId));
			tblUserPurseInfoMapper.insertSelective(purseInfo);
			
			//新增积分明细
			TblUserPurseInfo purseInfo1 = new TblUserPurseInfo();
			purseInfo1.setgContent("余额充值赠送积分");
			purseInfo1.setgCreatetime(new Date());
			purseInfo1.setgMoney((double)integral);
			purseInfo1.setgStatus(1);
			purseInfo1.setgTitle("余额充值赠送");
			purseInfo1.setgType(2);
			purseInfo1.setgBalance(user.getgUserIntegral()+integral);
			purseInfo1.setgUserid(Long.valueOf(userId));
			tblUserPurseInfoMapper.insertSelective(purseInfo1);
			
			int i = new Double(purseInfo1.getgBalance()).intValue();
			TblMessage record3 = new TblMessage();
			record3.setgContent("余额充值赠送"+integral+"积分,现有积分"+i);
			record3.setgTitle("积分提示");
			record3.setgType(2);
			record3.setgUserId(Long.valueOf(userId));
			record3.setgCreatetime(new Date());
			record3.setgVersion(1);
			tblMessageMapper.insertSelective(record3);
			return new ReturnData(200,"充值成功");
		}
		return null;
	}
	
	/**
     * 支付宝支付调用需要参数
     * @param body 订单描述
     * @param subject 订单标题
     * @param out_trade_no 	商户订单号 orderSn
     * @param total_amount 订单总金额，单位为元，精确到小数点后
     * @param order_id 回传参数
     * @return
     * @throws Exception
     */
    private ReturnData returnAlipayPayParam(String body, String subject, String out_trade_no, String total_amount, String order_id)throws Exception{
        String notify_url = AlipayCons.PAY_NOTIFY_URL;  //设置回调地址
        //公共参数,阿里的一些验证信息..
        Map<String, String> map = new HashMap<String, String>();
        map.put("app_id", AlipayCons.ALIPAY_APP_ID);
        map.put("method", "alipay.trade.app.pay");
        map.put("format", AlipayCons.ALIPAY_FORMAT);
        map.put("charset", AlipayCons.ALIPAY_CHARSET);
        map.put("sign_type", AlipayCons.ALIPAY_SIGN_TYPE);
        map.put("timestamp", DateUtils.getDateFormatter());
        map.put("version", "1.0");
        map.put("notify_url", notify_url);

        //业务参数,
        Map<String, String> m = new HashMap<String, String>();
        m.put("body", body);
        m.put("subject", subject);
        m.put("out_trade_no", out_trade_no);
        m.put("timeout_express", "30m");
        m.put("total_amount", total_amount);
        m.put("seller_id", AlipayCons.ALIPAY_PARTNER);
        m.put("product_code", "QUICK_MSECURITY_PAY");
        m.put("passback_params", order_id); // 回传参数，回调时原值返回
        //业务内容:json数据
        JSONObject bizcontentJson= JSONObject.fromObject(m);
        //将业务内容,放到map中,一起传递过去
        map.put("biz_content", bizcontentJson.toString());
        //对未签名原始字符串进行签名,,,对参数进行前面
        String rsaSign = AlipaySignature.rsaSign(map, AlipayCons.ALIPAY_PUBLIC_KEY, AlipayCons.ALIPAY_CHARSET);
        logger.info("====================================end AlipayService returnPayParam notify_url"+notify_url);
        //最后对请求字符串的所有一级value（biz_content作为一个value）进行encode，编码格式按请求串中的charset为准，没传charset按UTF-8处理
        map.put("biz_content", URLEncoder.encode(bizcontentJson.toString(), AlipayCons.ALIPAY_CHARSET));
        //Map par = AlipayUtil.paraFilter(map4); //除去数组中的空值和签名参数
        String json4 = AlipayUtil.createLinkString(map);   //拼接后的字符串
        StringBuffer jsonBuffer = new StringBuffer(json4).append("&sign=").append(URLEncoder.encode(rsaSign,AlipayCons.ALIPAY_CHARSET));
        logger.info("====================================end AlipayService returnPayParam"+jsonBuffer.toString());
        return new ReturnData(jsonBuffer.toString());
    }



    /**
     * 调用支付返回参数
     * @param body
     *            商品描述
     * @param out_trade_no
     *            商户订单号
     * @param total_fee
     *            标价金额
     * @param order_id
     *            回传参数
     * @return
     * @throws Exception
     */
    private ReturnData returnWXPayParam(String body, String out_trade_no, Integer total_fee, String order_id,
                                     String loca_ip) throws Exception {
        ReturnData returnData = new ReturnData();
        logger.info("returnPayParam ---" + body + ",,,out_trade_no=" + out_trade_no + ",total_fee=" + total_fee
                + ",,order_id=" + order_id);
        try {
            String nonce_str = getRandomString(32); // strTime + strRandom;
            // 获取发起电脑 ip
//            String loca_ip = request.getRemoteAddr();// 获得本机IP
            JSONObject jso = new JSONObject();
            // 账号信息
            String appid = WeixinCons.WX_APP_ID; // appid
            // String appsecret = WeixinCons.app_secret; // appsecret
            String mch_id = WeixinCons.WX_MACH_ID; // 商业号
            String api_key = WeixinCons.WX_APP_KEY; // key
            String notify_url = "";
            notify_url = WeixinCons.WX_PAY_NOTIFY_URL;
            logger.info("========================notify_url:" + notify_url);
            // 封装参数
            SortedMap<String, String> signParams = new TreeMap<String, String>();
            signParams.put("appid", appid);// app_id
            signParams.put("body", body);// 商品参数信息
            signParams.put("mch_id", mch_id);// 微信商户账号
            signParams.put("nonce_str", nonce_str);// 32位不重复的编号
            signParams.put("notify_url", notify_url);// 回调页面
            signParams.put("out_trade_no", out_trade_no);// 订单编号
            signParams.put("spbill_create_ip", loca_ip);// 请求的实际ip地址
            signParams.put("total_fee", String.valueOf(total_fee));// 支付金额 单位为分
            signParams.put("trade_type", "APP");// 付款类型为APP
            signParams.put("attach", order_id); // 附加数据，回调时原值返回
            String sign = WeixinPayUtil.createSign("UTF-8", signParams);// 生成签名
            signParams.put("sign", sign);
            signParams.remove("key");// 调用统一下单无需key（商户应用密钥）
            String requestXml = WeixinPayUtil.getRequestXml(signParams);// 生成Xml格式的字符串
            logger.info("----------------requestXML:" + requestXml);
            // 调用统一支付接口
            String resXml = HttpUtil.postData("https://api.mch.weixin.qq.com/pay/unifiedorder", requestXml);
            System.out.println("////////////////////////\n" + resXml);

            // 返回的result成功结果取出prepay_id：
            Map map = XMLUtil.doXMLParse(resXml);
            String return_code = (String) map.get("return_code");
            String return_msg = (String) map.get("return_msg");
            String prepay_id = null;
            if (return_code.contains("SUCCESS")) {
                prepay_id = (String) map.get("prepay_id");// 获取到prepay_id
            } else {
                returnData.setMsg("请求返回有误");
                returnData.setCode(2);
                returnData.setData(false);
                return returnData;
            }
            String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
            jso.put("appid", appid);// app_id
            jso.put("partnerid", mch_id);// 微信商户账号
            jso.put("prepayid", prepay_id);// 预付订单id
            jso.put("package", "Sign=WXPay");// 默认sign=WXPay
            jso.put("noncestr", nonce_str);// 自定义不重复的长度不长于32位
            jso.put("timestamp", timestamp);// 北京时间时间戳

            SortedMap<String, String> signParam = new TreeMap<String, String>();
            signParam.put("appid", appid);// app_id
            signParam.put("partnerid", mch_id);// 微信商户账号
            signParam.put("prepayid", prepay_id);// 预付订单id
            signParam.put("package", "Sign=WXPay");// 默认sign=WXPay
            signParam.put("noncestr", nonce_str);// 自定义不重复的长度不长于32位
            signParam.put("timestamp", timestamp);// 北京时间时间戳
            String signAgain = WeixinPayUtil.createSign("UTF-8", signParam);// 再次生成签名
            jso.put("sign", signAgain);

            System.out.println(jso);

            returnData = new ReturnData(jso);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return returnData;
    }

    /**
     * 表示生成字符串的长度
     *
     * @param length
     * @return
     */
    private static String getRandomString(int length) {
        String base = "abcdefghijklmnopqrstuvwxyz0123456789";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            int number = random.nextInt(base.length());
            sb.append(base.charAt(number));
        }
        return sb.toString();
    }


    /**
     * 开通会员微信回调
     * @param request
     * @param response
     * @throws Exception
     */
    public void wxNotify(HttpServletRequest request, HttpServletResponse response) throws Exception {
        logger.info("-------------------------------------------begin notify");
        try {
            // 读取参数
            InputStream inputStream;
            StringBuffer sb = new StringBuffer();
            inputStream = request.getInputStream();
            String s;
            BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
            while ((s = in.readLine()) != null) {
                sb.append(s);
            }
            in.close();
            inputStream.close();
            logger.info("-------------------------------------------begin notify s:" + sb.toString());
            // 解析xml成map
            Map<String, String> m = new HashMap<String, String>();
            m = XMLUtil.doXMLParse(sb.toString());
            logger.info("-------------------------------------------begin notify param:" + m);
            // 过滤空 设置 TreeMap
            SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();
            Iterator it = m.keySet().iterator();
            while (it.hasNext()) {
                String parameter = (String) it.next();
                String parameterValue = m.get(parameter);

                String v = "";
                if (null != parameterValue) {
                    v = parameterValue.trim();
                }
                packageParams.put(parameter, v);
            }

            // 账号信息
            String key = WeixinCons.WX_APP_KEY; // key

            logger.info(packageParams.toString());
            // 判断签名是否正确
            if (WeixinPayUtil.isTenpaySign("UTF-8", packageParams, key)) {
                // ------------------------------
                // 处理业务开始
                // ------------------------------
                String resXml = "";
                if ("SUCCESS".equals((String) packageParams.get("result_code"))) {
                    // 这里是支付成功
                    ////////// 执行自己的业务逻辑////////////////
                    String mch_id = (String) packageParams.get("mch_id");
                    String openid = (String) packageParams.get("openid");
                    String is_subscribe = (String) packageParams.get("is_subscribe");
                    String out_trade_no = (String) packageParams.get("out_trade_no");

                    String total_fee = (String) packageParams.get("total_fee");

                    logger.info("mch_id:" + mch_id);
                    logger.info("openid:" + openid);
                    logger.info("is_subscribe:" + is_subscribe);
                    logger.info("out_trade_no:" + out_trade_no);
                    logger.info("total_fee:" + total_fee);
                    ////////// 执行自己的业务逻辑////////////////
                    String attach = (String) packageParams.get("attach");
                    String[] split = attach.split(",");
                    Long userid = Long.parseLong(split[0]);
                    String vipid = split[1];
                    String payMoney = split[2];
                    String orderid = split[3];
                   /* //查看用户金额
                    TblUser user = tblUserMapper.selectByPrimaryKey(userid);
                    //减少用户钱包金额
        			TblUser tuser = new TblUser();
        			tuser.setgId(userid);
        			tuser.setgUserMoney(user.getgUserMoney() - Double.parseDouble(payMoney));
        			tuser.setgUserIsVip(vipid);
        			tuser.setgUserPayVipTime(new Date());
        			int flag1 = tblUserMapper.updateByPrimaryKeySelective(tuser);		*/
        			//添加会员订单
        			TblOrder order = new TblOrder();
        			order.setgOrderNo(orderid);
        			order.setgCreatetime(new Date());
        			order.setgOrderTotalMoney(Double.parseDouble(payMoney));
        			order.setgOrderPayMoney(Double.parseDouble(payMoney));
        			order.setgOrderStatus(1);
        			order.setgVersion(2);
        			order.setgOrderType(2);
        			order.setgUserId(userid);
        			order.setgGoodsName("开通会员");
        			order.setgGoodsId(vipid); //vipId
        			order.setgPayTime(new Date());  //购买时间
        			/*//增加余额明细
        			TblUser user = tblUserMapper.selectByPrimaryKey(userid);
        			//用户钱包金额
        			Double money = user.getgUserMoney();		
        			TblUserPurseInfo purseInfo = new TblUserPurseInfo();
        			purseInfo.setgContent("购买会员成功");
        			purseInfo.setgCreatetime(new Date());
        			purseInfo.setgMoney(Double.parseDouble(payMoney));
        			purseInfo.setgStatus(2);
        			purseInfo.setgTitle("购买会员");
        			purseInfo.setgType(1);
        			purseInfo.setgBalance(money - Double.parseDouble(payMoney));
        			purseInfo.setgUserid(userid.longValue());
        			tblUserPurseInfoMapper.insertSelective(purseInfo);*/
        			
        			TblVipInfo info = tblVipInfoMapper.selectByPrimaryKey(vipid);
        			//是否为续期(否：在当前时间追加会员期限   是：在有效期追加会员期限)
        			TblOrder tblOrder = tblOrderMapper.getVipInfo(userid);
        			Date validity = new Date();
        			if(tblOrder!=null){
        				if(validity.getTime()<=tblOrder.getgValidityTime().getTime()){
        					validity = tblOrder.getgValidityTime();
        				}	
        			}
        			Calendar calendar = new GregorianCalendar(); 
        		    calendar.setTime(validity); 
        		   
        			if(info.getgVipName().contains("月度")){
        				calendar.add(calendar.MONTH, 1);
    				}else if(info.getgVipName().contains("季度")){
    					calendar.add(calendar.MONTH, 3);
    				}else if(info.getgVipName().contains("年度")){
    					calendar.add(calendar.YEAR, 1);//把日期往后增加一年
    				}
        			order.setgValidityTime(calendar.getTime());
        			int flag = tblOrderMapper.insertSelective(order);
                    // 通知微信.异步确认成功.必写.不然会一直通知后台.八次之后就认为交易失败了.
                    resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
                            + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";

                } else {
                    logger.info("支付失败,错误信息：" + packageParams.get("err_code"));
                    resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
                            + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
                }
                // ------------------------------
                // 处理业务完毕
                // ------------------------------
                BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
                out.write(resXml.getBytes());
                out.flush();
                out.close();
            } else {
                logger.info("通知签名验证失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 支付宝回调
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    public String aliNotify(HttpServletRequest request,HttpServletResponse response) throws Exception {
        logger.info("====================================begin AlipayService notify");
        String returnStr = "";
        try {
            //读取参数
            InputStream inputStream ;
            StringBuffer sb = new StringBuffer();
            inputStream = request.getInputStream();
            String s ;
            BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
            while ((s = in.readLine()) != null){
                logger.info("====================================================param s:"+s);
                sb.append(s);
            }
            in.close();
            inputStream.close();
            logger.info("====================================================param InputStream:"+sb.toString());
            //接收支付宝返回的请求参数
            Map<String, String> params = AlipayUtil.createLinkMap(sb.toString());

            logger.info("====================================================param params:"+params);
            String trade_status = params.get("trade_status");
            String out_trade_no = params.get("out_trade_no");
            //String notify_id = json.get("notify_id").toString().substring(2,json.get("notify_id").toString().length()-2);

            logger.info("商户的订单编号：" + out_trade_no);
            logger.info("支付的状态：" + trade_status);

            if(trade_status != null && trade_status.equals("TRADE_SUCCESS")) {

                /**
                 *支付成功之后的业务处理
                 */
                String passback_params = params.get("passback_params");
                String[] split = passback_params.split(",");
                Long userid = Long.parseLong(split[0]);
                String vipid = split[1];
                String payMoney = split[2];
                String orderid = split[3];
                /*//查看用户金额
                TblUser user = tblUserMapper.selectByPrimaryKey(userid);
                //减少用户钱包金额
    			TblUser tuser = new TblUser();
    			tuser.setgId(userid);
    			tuser.setgUserMoney(user.getgUserMoney() - Double.parseDouble(payMoney));
    			tuser.setgUserIsVip(vipid);
    			tuser.setgUserPayVipTime(new Date());
    			int flag1 = tblUserMapper.updateByPrimaryKeySelective(tuser);		*/
    			//添加会员订单
    			TblOrder order = new TblOrder();
    			order.setgOrderNo(out_trade_no);
    			order.setgCreatetime(new Date());
    			order.setgOrderTotalMoney(Double.parseDouble(payMoney));
    			order.setgOrderPayMoney(Double.parseDouble(payMoney));
    			order.setgOrderStatus(1);
    			order.setgVersion(1);
    			order.setgOrderType(2);
    			order.setgUserId(userid);
    			order.setgGoodsName("开通会员");
    			order.setgGoodsId(vipid); //vipId
    			order.setgPayTime(new Date());  //购买时间
    			/*//增加余额明细
    			TblUser user = tblUserMapper.selectByPrimaryKey(userid);
    			//用户钱包金额
    			Double money = user.getgUserMoney();		
    			TblUserPurseInfo purseInfo = new TblUserPurseInfo();
    			purseInfo.setgContent("购买会员成功");
    			purseInfo.setgCreatetime(new Date());
    			purseInfo.setgMoney(Double.parseDouble(payMoney));
    			purseInfo.setgStatus(2);
    			purseInfo.setgTitle("购买会员");
    			purseInfo.setgType(1);
    			purseInfo.setgBalance(money - Double.parseDouble(payMoney));
    			purseInfo.setgUserid(userid.longValue());
    			tblUserPurseInfoMapper.insertSelective(purseInfo);*/
    			
    			TblVipInfo info = tblVipInfoMapper.selectByPrimaryKey(vipid);
    			//是否为续期(否：在当前时间追加会员期限   是：在有效期追加会员期限)
    			TblOrder tblOrder = tblOrderMapper.getVipInfo(userid);
    			Date validity = new Date();
    			if(tblOrder!=null){
    				if(validity.getTime()<=tblOrder.getgValidityTime().getTime()){
    					validity = tblOrder.getgValidityTime();
    				}	
    			}
    			Calendar calendar = new GregorianCalendar(); 
    		    calendar.setTime(validity); 
    		   
    			if(info.getgVipName().contains("月度")){
    				calendar.add(calendar.MONTH, 1);
				}else if(info.getgVipName().contains("季度")){
					calendar.add(calendar.MONTH, 3);
				}else if(info.getgVipName().contains("年度")){
					calendar.add(calendar.YEAR, 1);//把日期往后增加一年
				}
    			order.setgValidityTime(calendar.getTime());
    			int flag = tblOrderMapper.insertSelective(order);
            }else {

                /**
                 *支付失败后的业务处理
                 */
                returnStr = "ERROR";

            }
        } catch (Exception e) {
            e.printStackTrace();
            returnStr = "初始值";
        }
        logger.info("====================================end AlipayService notify"+returnStr);
        return returnStr;
    }


    /**
     * 余额充值微信回调
     * @param request
     * @param response
     * @throws Exception
     */
    public void wxBalance(HttpServletRequest request, HttpServletResponse response) throws Exception {
        logger.info("-------------------------------------------begin notify");
        try {
            // 读取参数
            InputStream inputStream;
            StringBuffer sb = new StringBuffer();
            inputStream = request.getInputStream();
            String s;
            BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
            while ((s = in.readLine()) != null) {
                sb.append(s);
            }
            in.close();
            inputStream.close();
            logger.info("-------------------------------------------begin notify s:" + sb.toString());
            // 解析xml成map
            Map<String, String> m = new HashMap<String, String>();
            m = XMLUtil.doXMLParse(sb.toString());
            logger.info("-------------------------------------------begin notify param:" + m);
            // 过滤空 设置 TreeMap
            SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();
            Iterator it = m.keySet().iterator();
            while (it.hasNext()) {
                String parameter = (String) it.next();
                String parameterValue = m.get(parameter);

                String v = "";
                if (null != parameterValue) {
                    v = parameterValue.trim();
                }
                packageParams.put(parameter, v);
            }

            // 账号信息
            String key = WeixinCons.WX_APP_KEY; // key

            logger.info(packageParams.toString());
            // 判断签名是否正确
            if (WeixinPayUtil.isTenpaySign("UTF-8", packageParams, key)) {
                // ------------------------------
                // 处理业务开始
                // ------------------------------
                String resXml = "";
                if ("SUCCESS".equals((String) packageParams.get("result_code"))) {
                    // 这里是支付成功
                    ////////// 执行自己的业务逻辑////////////////
                    String mch_id = (String) packageParams.get("mch_id");
                    String openid = (String) packageParams.get("openid");
                    String is_subscribe = (String) packageParams.get("is_subscribe");
                    String out_trade_no = (String) packageParams.get("out_trade_no");

                    String total_fee = (String) packageParams.get("total_fee");

                    logger.info("mch_id:" + mch_id);
                    logger.info("openid:" + openid);
                    logger.info("is_subscribe:" + is_subscribe);
                    logger.info("out_trade_no:" + out_trade_no);
                    logger.info("total_fee:" + total_fee);
                    ////////// 执行自己的业务逻辑////////////////
                    String attach = (String) packageParams.get("attach");
                    Double money = Double.parseDouble(total_fee)/100;
                    //计算赠送积分
                    TblIntegralSet integralSet = tblIntegralSetMapper.selectByType(1);
            	    int num = (int)Math.floor(money/integralSet.getMoney());
            	    int integral = num*integralSet.getIntegral();
                    
                    //查看用户金额
                    TblUser user = tblUserMapper.selectByPrimaryKey(Long.valueOf(attach));
                    //增加用户钱包金额
        			TblUser tuser = new TblUser();
        			tuser.setgId(Long.valueOf(attach));
        			tuser.setgUserMoney(user.getgUserMoney() + money);
        			tuser.setgUserIntegral(user.getgUserIntegral()+integral);
        			int flag1 = tblUserMapper.updateByPrimaryKeySelective(tuser);	
        			
        			//添加会员订单
        			TblOrder order = new TblOrder();
        			order.setgOrderNo(out_trade_no);
        			order.setgCreatetime(new Date());
        			order.setgOrderTotalMoney(money);
        			order.setgOrderPayMoney(money);
        			order.setgOrderStatus(1);
        			order.setgVersion(2);
        			order.setgOrderType(3);
        			order.setgUserId(Long.valueOf(attach));
        			order.setgGoodsName("充值余额");
        			order.setgGoodsId("0");
        			order.setgPayTime(new Date());  //购买时间
        			int flag = tblOrderMapper.insertSelective(order);
        			
        			//新增钱包明细
        			TblUserPurseInfo purseInfo = new TblUserPurseInfo();
        			purseInfo.setgContent("微信充值");
        			purseInfo.setgCreatetime(new Date());
        			purseInfo.setgMoney(money);
        			purseInfo.setgStatus(1);
        			purseInfo.setgTitle("微信充值");
        			purseInfo.setgType(1);
        			purseInfo.setgBalance(user.getgUserMoney() + money);
        			purseInfo.setgUserid(Long.valueOf(attach));
        			tblUserPurseInfoMapper.insertSelective(purseInfo);
        			
        			//新增积分明细
        			TblUserPurseInfo purseInfo1 = new TblUserPurseInfo();
        			purseInfo1.setgContent("余额充值赠送积分");
        			purseInfo1.setgCreatetime(new Date());
        			purseInfo1.setgMoney((double)integral);
        			purseInfo1.setgStatus(1);
        			purseInfo1.setgTitle("余额充值赠送");
        			purseInfo1.setgType(2);
        			purseInfo1.setgBalance(user.getgUserIntegral()+integral);
        			purseInfo1.setgUserid(Long.valueOf(attach));
        			tblUserPurseInfoMapper.insertSelective(purseInfo1);
        			
        			int i = new Double(purseInfo1.getgBalance()).intValue();
        			TblMessage record3 = new TblMessage();
        			record3.setgContent("余额充值赠送"+integral+"积分,现有积分"+i);
        			record3.setgTitle("积分提示");
        			record3.setgType(2);
        			record3.setgUserId(Long.valueOf(attach));
        			record3.setgCreatetime(new Date());
        			record3.setgVersion(1);
        			tblMessageMapper.insertSelective(record3);
                    // 通知微信.异步确认成功.必写.不然会一直通知后台.八次之后就认为交易失败了.
                    resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
                            + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";

                } else {
                    logger.info("支付失败,错误信息：" + packageParams.get("err_code"));
                    resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
                            + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
                }
                // ------------------------------
                // 处理业务完毕
                // ------------------------------
                BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
                out.write(resXml.getBytes());
                out.flush();
                out.close();
            } else {
                logger.info("通知签名验证失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 余额充值支付宝回调
     * @param request
     * @param response
     * @throws Exception
     */
	@Override
	public String aliRechargeNotify(HttpServletRequest request, HttpServletResponse response) throws Exception {
		logger.info("====================================begin AlipayService notify");
        String returnStr = "";
        try {
            //读取参数
            InputStream inputStream ;
            StringBuffer sb = new StringBuffer();
            inputStream = request.getInputStream();
            String s ;
            BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
            while ((s = in.readLine()) != null){
                logger.info("====================================================param s:"+s);
                sb.append(s);
            }
            in.close();
            inputStream.close();
            logger.info("====================================================param InputStream:"+sb.toString());
            //接收支付宝返回的请求参数
            Map<String, String> params = AlipayUtil.createLinkMap(sb.toString());

            logger.info("====================================================param params:"+params);
            String trade_status = params.get("trade_status");
            String out_trade_no = params.get("out_trade_no");
            String total_amount = params.get("total_amount");
            //String notify_id = json.get("notify_id").toString().substring(2,json.get("notify_id").toString().length()-2);

            logger.info("商户的订单编号：" + out_trade_no);
            logger.info("支付的状态：" + trade_status);

            if(trade_status != null && trade_status.equals("TRADE_SUCCESS")) {

                /**
                 *支付成功之后的业务处理
                 */
                String passback_params = params.get("passback_params");
                Double money = Double.parseDouble(total_amount);
                //计算赠送积分
                TblIntegralSet integralSet = tblIntegralSetMapper.selectByType(1);
        	    int num = (int)Math.floor(money/integralSet.getMoney());
        	    int integral = num*integralSet.getIntegral();
                
                //查看用户金额
                TblUser user = tblUserMapper.selectByPrimaryKey(Long.valueOf(passback_params));
                //增加用户钱包金额
    			TblUser tuser = new TblUser();
    			tuser.setgId(Long.valueOf(passback_params));
    			tuser.setgUserMoney(user.getgUserMoney() + money);
    			tuser.setgUserIntegral(user.getgUserIntegral()+integral);
    			int flag1 = tblUserMapper.updateByPrimaryKeySelective(tuser);	
    			
    			//添加会员订单
    			TblOrder order = new TblOrder();
    			order.setgOrderNo(out_trade_no);
    			order.setgCreatetime(new Date());
    			order.setgOrderTotalMoney(money);
    			order.setgOrderPayMoney(money);
    			order.setgOrderStatus(1);
    			order.setgVersion(1);
    			order.setgOrderType(3);
    			order.setgUserId(Long.valueOf(passback_params));
    			order.setgGoodsName("充值余额");
    			order.setgGoodsId("0");
    			order.setgPayTime(new Date());  //购买时间
    			int flag = tblOrderMapper.insertSelective(order);
    			
    			//新增钱包明细
    			TblUserPurseInfo purseInfo = new TblUserPurseInfo();
    			purseInfo.setgContent("支付宝充值");
    			purseInfo.setgCreatetime(new Date());
    			purseInfo.setgMoney(money);
    			purseInfo.setgStatus(1);
    			purseInfo.setgTitle("支付宝充值");
    			purseInfo.setgType(1);
    			purseInfo.setgBalance(user.getgUserMoney() + money);
    			purseInfo.setgUserid(Long.valueOf(passback_params));
    			tblUserPurseInfoMapper.insertSelective(purseInfo);
    			
    			//新增积分明细
    			TblUserPurseInfo purseInfo1 = new TblUserPurseInfo();
    			purseInfo1.setgContent("余额充值赠送积分");
    			purseInfo1.setgCreatetime(new Date());
    			purseInfo1.setgMoney((double)integral);
    			purseInfo1.setgStatus(1);
    			purseInfo1.setgTitle("余额充值赠送");
    			purseInfo1.setgType(2);
    			purseInfo1.setgBalance(user.getgUserIntegral()+integral);
    			purseInfo1.setgUserid(Long.valueOf(passback_params));
    			tblUserPurseInfoMapper.insertSelective(purseInfo1);
    			
    			int i = new Double(purseInfo1.getgBalance()).intValue();
    			TblMessage record3 = new TblMessage();
    			record3.setgContent("余额充值赠送"+integral+"积分,现有积分"+i);
    			record3.setgTitle("积分提示");
    			record3.setgType(2);
    			record3.setgUserId(Long.valueOf(passback_params));
    			record3.setgCreatetime(new Date());
    			record3.setgVersion(1);
    			tblMessageMapper.insertSelective(record3);
            }else {

                /**
                 *支付失败后的业务处理
                 */
                returnStr = "ERROR";

            }
        } catch (Exception e) {
            e.printStackTrace();
            returnStr = "初始值";
        }
        logger.info("====================================end AlipayService notify"+returnStr);
        return returnStr;
	}
	
	/**
     * 购买课程支付宝回调
     */
	@Override
	public String payCourseNotify(HttpServletRequest request, HttpServletResponse response) throws Exception {
		logger.info("====================================begin AlipayService notify");
		String returnStr = "";
		try {
			//读取参数
			InputStream inputStream ;
			StringBuffer sb = new StringBuffer();
			inputStream = request.getInputStream();
			String s ;
			BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
			while ((s = in.readLine()) != null){
				logger.info("====================================================param s:"+s);
				sb.append(s);
			}
			in.close();
			inputStream.close();
			logger.info("====================================================param InputStream:"+sb.toString());
			//接收支付宝返回的请求参数
			Map<String, String> params = AlipayUtil.createLinkMap(sb.toString());
			
			logger.info("====================================================param params:"+params);
			String trade_status = params.get("trade_status");
			String out_trade_no = params.get("out_trade_no");
			String total_amount = params.get("total_amount");
			//String notify_id = json.get("notify_id").toString().substring(2,json.get("notify_id").toString().length()-2);
			
			logger.info("商户的订单编号：" + out_trade_no);
			logger.info("支付的状态：" + trade_status);
			
			if(trade_status != null && trade_status.equals("TRADE_SUCCESS")) {
				
				/**
				 *支付成功之后的业务处理
				 */
				
				//增加用户积分
				/*Map<String,Object> map = new HashMap<>();
				map.put("userid", Integer.parseInt(param[0]));
				map.put("integral", Integer.parseInt(param[1]));
				tblCourseMapper.minusUserMoney(map);*/
				//修改订单状态
				tblCourseMapper.updateOrderStatus(out_trade_no,"1");
				/*if(Integer.parseInt(param[1]) > 0){
					//增加消息表记录
					Map<String,Object> hashMap = new HashMap<>();
					hashMap.put("userid", Integer.parseInt(param[0]));
					hashMap.put("content", "购买成功，本次购买获得" + Integer.parseInt(param[1]) + "积分");
					hashMap.put("title", "购买课程");
					hashMap.put("type", 2);
					tblCourseMapper.insertMessageRecord(hashMap);
				}*/
				/*//查看用户余额
				Map<String, Object> userInfo = tblCourseMapper.selectUserInfo( Integer.parseInt(param[0]));
				//增加余额明细
				TblUserPurseInfo purseInfo = new TblUserPurseInfo();
				purseInfo.setgContent("购买课程");
				purseInfo.setgCreatetime(new Date());
				purseInfo.setgMoney(money);
				purseInfo.setgStatus(2);
				purseInfo.setgTitle("购买课程");
				purseInfo.setgType(1);
				purseInfo.setgBalance((Double)userInfo.get("G_USER_MONEY"));
				purseInfo.setgUserid(Long.parseLong(param[0]));
				tblUserPurseInfoMapper.insertSelective(purseInfo);*/
				//根据订单id查询课程id
				/*Integer[] courseid = tblCourseMapper.selectCourseid(param[1]);
				for(int i = 0;i < courseid.length;i++){
					Map<String, Object> courseInfo = tblCourseMapper.selectCourseInfo(courseid[i],null);
					//增加该课程的学习人数
					tblCourseMapper.updateCourseStudyNum(courseid[i],courseInfo.get("G_RELATED_COURSE").toString().split(",").length);
				}*/
			}else {
				
				/**
				 *支付失败后的业务处理
				 */
				returnStr = "ERROR";
				
			}
		} catch (Exception e) {
			e.printStackTrace();
			returnStr = "初始值";
		}
		logger.info("====================================end AlipayService notify"+returnStr);
		return returnStr;
	}
	
	/**
     * 购买课程微信回调
     */
	 public void wxPayCourse(HttpServletRequest request, HttpServletResponse response) throws Exception {
	        logger.info("-------------------------------------------begin notify");
	        try {
	            // 读取参数
	            InputStream inputStream;
	            StringBuffer sb = new StringBuffer();
	            inputStream = request.getInputStream();
	            String s;
	            BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
	            while ((s = in.readLine()) != null) {
	                sb.append(s);
	            }
	            in.close();
	            inputStream.close();
	            logger.info("-------------------------------------------begin notify s:" + sb.toString());
	            // 解析xml成map
	            Map<String, String> m = new HashMap<String, String>();
	            m = XMLUtil.doXMLParse(sb.toString());
	            logger.info("-------------------------------------------begin notify param:" + m);
	            // 过滤空 设置 TreeMap
	            SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();
	            Iterator it = m.keySet().iterator();
	            while (it.hasNext()) {
	                String parameter = (String) it.next();
	                String parameterValue = m.get(parameter);

	                String v = "";
	                if (null != parameterValue) {
	                    v = parameterValue.trim();
	                }
	                packageParams.put(parameter, v);
	            }

	            // 账号信息
	            String key = WeixinCons.WX_APP_KEY; // key

	            logger.info(packageParams.toString());
	            // 判断签名是否正确
	            if (WeixinPayUtil.isTenpaySign("UTF-8", packageParams, key)) {
	                // ------------------------------
	                // 处理业务开始
	                // ------------------------------
	                String resXml = "";
	                if ("SUCCESS".equals((String) packageParams.get("result_code"))) {
	                    // 这里是支付成功
	                    ////////// 执行自己的业务逻辑////////////////
	                    String mch_id = (String) packageParams.get("mch_id");
	                    String openid = (String) packageParams.get("openid");
	                    String is_subscribe = (String) packageParams.get("is_subscribe");
	                    String out_trade_no = (String) packageParams.get("out_trade_no");

	                    String total_fee = (String) packageParams.get("total_fee");

	                    logger.info("mch_id:" + mch_id);
	                    logger.info("openid:" + openid);
	                    logger.info("is_subscribe:" + is_subscribe);
	                    logger.info("out_trade_no:" + out_trade_no);
	                    logger.info("total_fee:" + total_fee);
	                    ////////// 执行自己的业务逻辑////////////////
	                    String attach = (String) packageParams.get("attach");
	                    Double money = Double.parseDouble(total_fee)/100;
	                   
	                    String[] param = attach.split(",");
	    				//修改订单状态
	    				tblCourseMapper.updateOrderStatus(param[1],"2");
	    				/*if(Integer.parseInt(param[1]) > 0){
		    				//增加消息表记录
		    				Map<String,Object> hashMap = new HashMap<>();
		    				hashMap.put("userid", Integer.parseInt(param[0]));
		    				hashMap.put("content", "购买成功，本次购买获得" + Integer.parseInt(param[1]) + "积分");
		    				hashMap.put("title", "购买课程");
		    				hashMap.put("type", 2);
		    				tblCourseMapper.insertMessageRecord(hashMap);
	    				}	*/
	    				/*//查看用户余额
	    				Map<String, Object> userInfo = tblCourseMapper.selectUserInfo( Integer.parseInt(param[0]));
	    				//增加余额明细
	    				TblUserPurseInfo purseInfo = new TblUserPurseInfo();
	    				purseInfo.setgContent("购买课程");
	    				purseInfo.setgCreatetime(new Date());
	    				purseInfo.setgMoney(money);
	    				purseInfo.setgStatus(2);
	    				purseInfo.setgTitle("购买课程");
	    				purseInfo.setgType(1);
	    				purseInfo.setgBalance((Double)userInfo.get("G_USER_MONEY"));
	    				purseInfo.setgUserid(Long.parseLong(param[0]));
	    				tblUserPurseInfoMapper.insertSelective(purseInfo);*/
	    				//根据订单id查询课程id
	    				/*Integer[] courseid = tblCourseMapper.selectCourseid(param[1]);
	    				for(int i = 0;i < courseid.length;i++){
	    					Map<String, Object> courseInfo = tblCourseMapper.selectCourseInfo(courseid[i],null);
	    					//增加该课程的学习人数
	    					tblCourseMapper.updateCourseStudyNum(courseid[i],courseInfo.get("G_RELATED_COURSE").toString().split(",").length);
	    				}*/
	                    // 通知微信.异步确认成功.必写.不然会一直通知后台.八次之后就认为交易失败了.
	                    resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
	                            + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";

	                } else {
	                    logger.info("支付失败,错误信息：" + packageParams.get("err_code"));
	                    resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
	                            + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
	                }
	                // ------------------------------
	                // 处理业务完毕
	                // ------------------------------
	                BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
	                out.write(resXml.getBytes());
	                out.flush();
	                out.close();
	            } else {
	                logger.info("通知签名验证失败");
	            }
	        } catch (Exception e) {
	            e.printStackTrace(); 
	        }
	    }

}